]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
windowPreview: Adjust WindowPreview stack when stackAbove overlay shown
authorKeyu Tao <me@taoky.moe>
Sat, 31 Aug 2024 13:51:34 +0000 (21:51 +0800)
committerMarge Bot <marge-bot@gnome.org>
Thu, 13 Feb 2025 12:38:19 +0000 (12:38 +0000)
When there are 3 or more windows in WorkspaceLayout, showing or hiding
window preview overlay in some certain orders could cause
inconsistencies in windows' vertical arrangement.

Let's take window A, B, C as an example. Initially, A is above B and B
is above C in workspace layout like this: A -> B -> C.

After opening activities, user could:

1. Move cursor to B preview, which would move B above all in layout:
   B -> A -> C
2. Move cursor from B to C preview. When C's showOverlay() is called
   before B's hideOverlay(), _restack() would move C above all and don't
   change B's arrangement:
   C -> B -> A
3. Finally, move cursor away from C's preview:
   B -> A -> C

In this case, when user closes Activities, they would see window
stacking wrong for a while.

This commit adds some extra logic in _restack, checking the
_stackAbove's _stackAbove when this._stackAbove._overlayShown is true.
Though it's still not guaranteed to be always consistent as there could
be several WindowPreview with _overlayShown as true if pointer moves
really fast, this helps avoid glitches in many cases.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4638.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3460>

js/ui/windowPreview.js

index cf3fbdaa6f8d71d97bedb8be28bcfe65c9e78be7..95a2276ca6e60a46381e1fc457df084aff398566 100644 (file)
@@ -621,12 +621,20 @@ export const WindowPreview = GObject.registerClass({
         // with a new one on the target workspace.
         const parent = this.get_parent();
         if (parent !== null) {
-            if (this._overlayShown)
+            if (this._overlayShown) {
                 parent.set_child_above_sibling(this, null);
-            else if (this._stackAbove === null)
+            } else if (this._stackAbove === null) {
                 parent.set_child_below_sibling(this, null);
-            else if (!this._stackAbove._overlayShown)
+            } else if (!this._stackAbove._overlayShown) {
                 parent.set_child_above_sibling(this, this._stackAbove);
+            } else {
+                // This window shall still be above this._stackAbove._stackAbove
+                const above = this._stackAbove._stackAbove;
+                if (above === null)
+                    parent.set_child_below_sibling(this, null);
+                else
+                    parent.set_child_above_sibling(this, above);
+            }
         }
     }